package me

import (
	"context"
	"path/filepath"
	"slices"
	"strings"
	"time"

	"fyne.io/fyne/v2"
	"github.com/gabriel-vasile/mimetype"
	"github.com/gogf/gf/v2/os/gfile"
	"golang.org/x/text/encoding/simplifiedchinese"
	"golang.org/x/text/transform"
)

func SetObjs(c *fyne.Container, objs ...fyne.CanvasObject) {
	c.Objects = objs
	c.Refresh()
}

// GBK -> UTF-8
func GbkToUtf8(s []byte) []byte {
	bs, _, err := transform.Bytes(simplifiedchinese.GBK.NewDecoder(), s)
	if err != nil {
		return s
	}
	return bs
}

func IsText(textfile string) bool {
	if !gfile.DefaultPermOpen.IsRegular() {
		return false
	}
	if slices.Contains(ExtText, gfile.ExtName(textfile)) {
		return true
	}

	mtype, err := mimetype.DetectFile(textfile)
	if err != nil {
		return false
	}
	if strings.Split(mtype.String(), "/")[0] == "text" {
		return true
	}
	return false
}

func IsImage(imagefile string) bool {
	if !gfile.DefaultPermOpen.IsRegular() {
		return false
	}
	if slices.Contains(ExtImage, gfile.Ext(imagefile)) {
		return true
	}

	return false
}

func IsGif(fpath string) bool {
	if !gfile.DefaultPermOpen.IsRegular() {
		return false
	}

	return strings.ToLower(filepath.Ext(fpath)) == ".gif"
}

// https://blog.csdn.net/weixin_44879611/article/details/115537192
func AsyncCall(outi time.Duration, fn, fn1 func()) {
	ctx, cancel := context.WithTimeout(Ctx, time.Duration(time.Second*outi))
	defer cancel()
	done := make(chan struct{}, 1)
	go func() {
		if fn != nil {
			fn()
		}
		done <- struct{}{}
	}()

	select {
	case <-done:
		return
	case <-ctx.Done():
		if fn1 != nil {
			fn1()
		}
	}
}

// 异步执行函数 fn , 超时取消执行 fn ，同时执行函数 fn1
func AsyncCall1(outi time.Duration, fn, fn1 func()) {
	done := make(chan struct{}, 1)
	go func() {
		if fn != nil {
			fn()
		}
		done <- struct{}{}
	}()

	select {
	case <-done:
		// fmt.Println("call successfully!!!")
		return
	case <-time.After(time.Duration(outi * time.Second)):
		// fmt.Println("timeout!!!")
		if fn1 != nil {
			fn1()
		}
		return
	}
}
